﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Runtime.Serialization;

namespace PedesTrainProject.Traffic
{
    [Serializable()]
    public class Pedestrian : TrafficMember, ISerializable
    {
        private int tile_index;
        private Vector tile_position;

        public Pedestrian(int _tile_index, Core.ICoreTraffic _coreTraffic)
        {
            tile_index = _tile_index;
            coreTraffic = _coreTraffic;
            randomizePosition();
        }

        public List<Grid.Tile> calculatePath(Grid.Tile starter, Grid.Tile destination) //modify return in class diag.
        {
            return null;
        }

        private void randomizePosition()
        {
            Random rand = new Random();
            Vector available_pixels = getAvailablePixels();

            int pos_x = 0, pos_y = 0;
            bool border_x = false, border_y = false;

            if (available_pixels.X != -1 && available_pixels.Y != -1)
            {
                int random_border = rand.Next(0, 1);
                if (random_border == 0) border_x = true;
                else border_y = true;
            }
            else if (available_pixels.X != -1) border_x = true;
            else if (available_pixels.Y != -1) border_y = true;

            if (available_pixels.X != -1 && border_x)
            {
                if (available_pixels.X != 0 && available_pixels.X != 100)
                {
                    int rand_x = rand.Next(0, (int)available_pixels.X);
                    if (rand_x >= available_pixels.X / 2) pos_x = 100 + (int)available_pixels.X / 2 - rand_x;
                }
                else pos_x = (int)available_pixels.X;
            }

            else if (available_pixels.Y != -1 && border_y)
            {
                if (available_pixels.Y != 0 && available_pixels.Y != 100)
                {
                    int rand_y = rand.Next(0, (int)available_pixels.Y);
                    if (rand_y >= available_pixels.Y / 2) pos_y = 100 + (int)available_pixels.Y / 2 - rand_y;
                }
                else pos_y = (int)available_pixels.Y;
            }

            tile_position = new Vector(pos_x, pos_y);

            position = Core.Calculations.gridPosition(tile_index);
            position.X = position.X * 100 + pos_x;
            position.Y = position.Y * 100 + pos_y;
        }

        public void go()
        {
            Random rand = new Random();
            int random = rand.Next(0, 4);
            if (random == 0) position.Y--;
            else if (random == 1) position.X++;
            else if (random == 2) position.Y++;
            else position.X--;
        }

        public void stop()
        {

        }

        public bool move()
        {
            Random rand = new Random();
            int random = rand.Next(0, 4);
            Vector pos = tile_position;

            if (random == 0) pos.Y--;
            else if (random == 1) pos.X++;
            else if (random == 2) pos.Y++;
            else pos.X--;

            int temp_tile_index = tile_index;
            if (pos.X < 0) temp_tile_index--;
            else if (pos.X > 100) temp_tile_index++;
            else if (pos.Y < 0) temp_tile_index -= 4;
            else if (pos.Y > 100) temp_tile_index += 4;

            if (temp_tile_index > 0 && temp_tile_index < 16) tile_index = temp_tile_index;
            else return false;

            if ((pos.X < 30 || pos.X > 70) && (pos.X < 30 || pos.X > 70))
            {
                position.X = Core.Calculations.gridPosition(tile_index).X * 100 + pos.X;
                position.Y = Core.Calculations.gridPosition(tile_index).Y * 100 + pos.Y;
            }
            return true;
        }

        private Vector getAvailablePixels()
        {
            Grid.Grid grid = coreTraffic.getGrid();
            Grid.Tile tile = grid.Tiles[tile_index];

            Vector available_pixels = new Vector(-1, -1);

            if (tile_index >= 0 && tile_index < grid.Width) available_pixels.X = 0;
            if (tile_index % grid.Width == 0) available_pixels.Y = 0;
            if (tile_index >= grid.Tiles.Count - grid.Width && tile_index < grid.Tiles.Count) available_pixels.X = 100;
            if ((tile_index + 1) % grid.Width == 0) available_pixels.Y = 100;

            for (int i = 0; i < tile.Road.Lanes.Count; i++)
            {
                Grid.Lane lane = tile.Road.Lanes[i];
                if (lane.Direction == Grid.Directions.North && available_pixels.X == 0) available_pixels.Y = 60;
                else if (lane.Direction == Grid.Directions.West && available_pixels.Y == 0) available_pixels.X = 60;
                else if (lane.Direction == Grid.Directions.South && available_pixels.X == 100) available_pixels.Y = 60;
                else if (lane.Direction == Grid.Directions.East && available_pixels.Y == 100) available_pixels.X = 60;
            }

            return available_pixels;
        }

        public void animate()
        {
            coreTraffic.animatePedestrian(position);
        }

        #region Serialize
        public Pedestrian(SerializationInfo info, StreamingContext ctxt)
        {
            this.position = (Vector)info.GetValue("Position", typeof(Vector));
            this.absolute_position = (Vector)info.GetValue("Absolute_Position", typeof(Vector));
            this.starter = (int)info.GetValue("Starter", typeof(int));
            this.destination = (int)info.GetValue("Destination", typeof(int));
            this.skin = (string)info.GetValue("Skin", typeof(string));
        }

        public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
        {
            info.AddValue("Position", this.position);
            info.AddValue("Absolute_Position", this.absolute_position);
            info.AddValue("Starter", this.starter);
            info.AddValue("Destination", this.destination);
            info.AddValue("Skin", this.skin);
        }
        #endregion
    }
}
